/*
 ============================================================================
 Name        : wallpapers.c
 Author      : alexds9
 Version     :
 Copyright   : NO
 Description : Create collection of wallpapers for Ubuntu:
 	 	 	   In Ubuntu in order to create collection of wallpapers two xml files need to be created, in path:
 	 	 	   1) "/usr/share/backgrounds/"
 	 	 	   2) "/usr/share/gnome-background-properties/"
 	 	 	   First one contains the pictures' paths and order of pictures. The second one contains info about the first one.
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <time.h>

#define IMAGE_VIEW_TIME_DEFAULT 		45.0
#define IMAGE_TRANSITION_TIME_DEFAULT 	0.0
#define COLLECTION_PATH 				"/usr/share/backgrounds/"
#define CONFIGURATION_PATH				"/usr/share/gnome-background-properties/"
#define BUFFER_SIZE 					1024
#define MAX_CHAR_TO_READ				BUFFER_SIZE - 1
#define SOFT_ASSERT(CONDITION)			if (! (CONDITION)){ \
											fprintf(stdout,"[ERROR] %s", #CONDITION); \
										}				

int find_file_ext_index(char *file_name){
	int  index_of_point;
	char *place_of_point = strrchr(file_name,'.');

	if (!place_of_point){
		return -1;
	}else{
		index_of_point = place_of_point - file_name;
		if (strlen(file_name) == index_of_point + 1){
			return -1;
		}else{
			return index_of_point + 1;
		}
	}
}

char char_to_low(char c){
	if ('A' <= c && c <= 'Z'){
		return c - 'A' + 'a';
	}else{
		return c;
	}
}

int string_compare_not_case_sensitive(char *str1,char *str2){
	int is_equal = 1;
	int i = 0;
	int ended = 0;

	while (is_equal && !ended){

		if (char_to_low(str1[i]) != char_to_low(str2[i])){
			is_equal = 0;
		}else{
			ended = str1[i] == '\0';
		}
		i++;
	}

	return is_equal;
}


int find_index_of_string_in_array(int size, char *arr[],char *s){
	int i = 0;
	int found = 0;

	while (i < size && !found){
		found = strcmp(s,arr[i]) == 0;
		i++;
	}

	if (found){
		return i - 1;
	}else{
		return -1;
	}
}


int find_index_in_array_of_arguments_by_prefix(int argc, char *argv[],char *prefix){
	int i = find_index_of_string_in_array(argc, argv,prefix);

	if (i == -1){
		return -1;
	}else{
		return i + 1;
	}
}


void randomize_array(int size, char *arr[]){
	int i;
	char *s;
	int rand_i;
	srand(time(NULL));

	for (i = size - 1; i > 0; i--){
		rand_i = rand() % (i + 1);
		s = arr[i];
		arr[i] = arr[rand_i];
		arr[rand_i] = s;
	}

}
// IMAGE_VIEW_TIME_DEFAULT
// IMAGE_TRANSITION_TIME_DEFAULT

int get_input_arguments(char **p_collection_name, char **p_path_to_collection,
						float *image_view_time, float *image_transition_time,
						int argc, char *argv[]){
	char buffer[BUFFER_SIZE];
	int is_input_ok = 1;
	int tmp_i;


	/**
	*	prefix: -cn = name of collection, file with that name will be created in "/usr/share/backgrounds", with extension xml
	*	prefix: -cp = path to the pictures
	*	prefix: -vt = image view time
	*	prefix: -tt = image transition time
	*/
	if (argc == 1){ // check arguments
		fprintf(stdout, "Collection name: ");
		SOFT_ASSERT(fgets(buffer,MAX_CHAR_TO_READ,stdin));
		*p_collection_name = (char *)malloc(strlen(buffer)+1);
		strcpy(*p_collection_name, buffer);
		fprintf(stdout, "Path to collection: ");
		SOFT_ASSERT(fgets(buffer,MAX_CHAR_TO_READ,stdin));
		*p_path_to_collection = (char *)malloc(strlen(buffer)+1);
		strcpy(*p_path_to_collection, buffer);
		fprintf(stdout, "View time: ");
		SOFT_ASSERT(fscanf(stdin,"%f",image_view_time));
		fprintf(stdout, "Transition time: ");
		SOFT_ASSERT(fscanf(stdin,"%f",image_transition_time));
	}else{
		if(find_index_of_string_in_array(argc, argv,"--help") != -1){
			fprintf(stdout,"WALLPAPERS\t\t\tUser Commands\t\t\tWALLPAPERS\n\n");
			fprintf(stdout,"\e[1;1mNAME\e[0m\n");
			fprintf(stdout,"\twallpapers - create collection of wallpapers in Ubuntu\n");
			fprintf(stdout,"\e[1;1mSYNOPSIS\e[0m\n");
			fprintf(stdout,"\t\e[1;1mwallpapers\e[0m \e[1;4mOPTION\e[0m\n");
			fprintf(stdout,"\t\e[1;1mwallpapers\e[0m\n");
			fprintf(stdout,"\e[1;1mDESCRIPTION\e[0m\n");
			fprintf(stdout,"\t\tAdministrator privileges needed.\n");
			fprintf(stdout,"\t\e[1;1m-cn\e[0m\n");
			fprintf(stdout,"\t\tname of collection, file with that name will be created in \"/usr/share/backgrounds\", with extension xml.\n");
			fprintf(stdout,"\t\e[1;1m-cp\e[0m\n");
			fprintf(stdout,"\t\tpath to the pictures.\n");
			fprintf(stdout,"\t\e[1;1m-vt\e[0m\n");
			fprintf(stdout,"\t\timage view time.\n");
			fprintf(stdout,"\t\e[1;1m-tt\e[0m\n");
			fprintf(stdout,"\t\timage transition time.\n");
			fprintf(stdout,"\e[1;1mEXAMPLE\e[0m\n");
			fprintf(stdout,"\t\tsudo ./wallpapers -cn \"wallpapers 4.9.2010\" -cp \"/media/D/Wallpapers/4.9.2010\" -vt 45 -tt 0\n");
			fprintf(stdout,"\e[1;1mAUTHOR\e[0m\n");
			fprintf(stdout,"\t\talexds9.\n");
			fprintf(stdout,"\e[1;1mCOPYRIGHT\e[0m\n");
			fprintf(stdout,"\t\tCopyright  ©  2010 alexds9.\n");

			is_input_ok = -1;
		}else{

			tmp_i = find_index_in_array_of_arguments_by_prefix(argc, argv,"-cn");

			if (tmp_i != -1){
				*p_collection_name = (char *)malloc(strlen(argv[tmp_i])+1);
				strcpy(*p_collection_name, argv[tmp_i]);


				tmp_i = find_index_in_array_of_arguments_by_prefix(argc, argv,"-cp");

				if (tmp_i != -1){
					*p_path_to_collection = (char *)malloc(strlen(argv[tmp_i])+1);
					strcpy(*p_path_to_collection, argv[tmp_i]);

					tmp_i = find_index_in_array_of_arguments_by_prefix(argc, argv,"-vt");

					if (tmp_i != -1){

						if (sscanf(argv[tmp_i],"%f",image_view_time) == 0){
							*image_view_time = IMAGE_VIEW_TIME_DEFAULT;
						}
					}


					tmp_i = find_index_in_array_of_arguments_by_prefix(argc, argv,"-tt");

					if (tmp_i != -1){
						if (sscanf(argv[tmp_i],"%f",image_transition_time) == 0){
							*image_transition_time = IMAGE_TRANSITION_TIME_DEFAULT;
						}
					}

				}else{
					is_input_ok = 0;
				}

			}else{
				is_input_ok = 0;
			}
		}

	}

	//fprintf(stdout,"name:            %s\n",*p_collection_name);
	//fprintf(stdout,"path:            %s\n",*p_path_to_collection);
	//fprintf(stdout,"view time:       %f\n",image_view_time);
	//fprintf(stdout,"transition time: %f\n",image_transition_time);
	return is_input_ok;
}


int main(int argc, char *argv[]) {
	DIR *wallpapers_directory;
	struct dirent *directory_entry;
	int ext_found;
	int j;
	char *extensions_supported[] = {"png","jpg","gif","bmp"};
	int ext_index;
	char *ext;
	int i;
	FILE *fp_collection = NULL;
	FILE *fp_configurations = NULL;
	char collection_file_name[4096];
	char configurations_file_name[4096];
	char *files_names[4096];
	int files_amount = 0;
	int h;
	char *collection_name;
	char *path_to_collection;
	float image_view_time;
	float image_transition_time;
	int input_state;


	input_state = get_input_arguments(&collection_name, &path_to_collection,
				  &image_view_time, &image_transition_time,
				  argc, argv);
	if (input_state == 0){
		fprintf(stderr, "Not enough arguments.");
		return EXIT_FAILURE;
	}

	if (input_state == -1){ // on --help
		return EXIT_SUCCESS;
	}

	wallpapers_directory = opendir(path_to_collection); // open directory of wallpapers
	if (!wallpapers_directory){
		fprintf(stderr, "Folder path don't exist.");
		return EXIT_FAILURE;

	}

	directory_entry = readdir(wallpapers_directory);

	strcpy(collection_file_name,COLLECTION_PATH);
	strcat(collection_file_name, collection_name);
	strcat(collection_file_name, ".xml");

	fp_collection = fopen(collection_file_name,"w");
	if (fp_collection == NULL){
		fprintf(stderr,"\"%s\" not loaded.\n", collection_file_name);
		return EXIT_FAILURE;
	}

	fprintf(fp_collection,"<background>\n");
	fprintf(fp_collection,"\t<starttime>\n");
	fprintf(fp_collection,"\t\t<year>2010</year>\n");
	fprintf(fp_collection,"\t\t<month>01</month>\n");
	fprintf(fp_collection,"\t\t<day>01</day>\n");
	fprintf(fp_collection,"\t\t<hour>00</hour>\n");
	fprintf(fp_collection,"\t\t<minute>00</minute>\n");
	fprintf(fp_collection,"\t\t<second>00</second>\n");
	fprintf(fp_collection,"\t</starttime>\n");

	strcpy(configurations_file_name,CONFIGURATION_PATH);
	strcat(configurations_file_name, collection_name);
	strcat(configurations_file_name, ".xml");

	fp_configurations = fopen(configurations_file_name,"w");
	if (fp_configurations == NULL){
		fprintf(stderr,"\"%s\" not loaded.\n", configurations_file_name);
		return EXIT_FAILURE;
	}

	fprintf(fp_configurations,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
	fprintf(fp_configurations,"<!DOCTYPE wallpapers SYSTEM \"gnome-wp-list.dtd\">\n");
	fprintf(fp_configurations,"<wallpapers>\n");
	fprintf(fp_configurations,"\t<wallpaper deleted=\"false\">\n");
	fprintf(fp_configurations,"\t\t<name>%s</name>\n",collection_file_name);
	fprintf(fp_configurations,"\t\t<filename>%s</filename>\n",collection_file_name);
	fprintf(fp_configurations,"\t\t<options>zoom</options>\n");
	fprintf(fp_configurations,"\t</wallpaper>\n");
	fprintf(fp_configurations,"</wallpapers>\n");


	fclose(fp_configurations);

	i = 0;

	while (directory_entry){// move over directory entries, to find if file is image of supported extensions,
							// add it to array of images that will be randomized and exported to xml file of collection

		ext_index = find_file_ext_index(directory_entry->d_name);

		if (ext_index > -1){
			ext = (char *)(directory_entry->d_name + ext_index);

			ext_found = 0;
			j = 0;
			while (j < sizeof(extensions_supported)/sizeof(char *) && !ext_found){

				ext_found = string_compare_not_case_sensitive(extensions_supported[j],ext);
				j++;
			}

			if (ext_found){

				files_names[files_amount] = (char *)malloc(strlen(directory_entry->d_name) + 1);
				strcpy(files_names[files_amount],directory_entry->d_name);

				files_amount++;

			}
		}

		i++;

		directory_entry = readdir(wallpapers_directory);
	}

	randomize_array(files_amount, files_names);

	for (h = 0; h < files_amount - 1; h++){

		fprintf(fp_collection,"\t<static>\n");
		fprintf(fp_collection,"\t\t<duration>%f</duration>\n",image_view_time);
		fprintf(fp_collection,"\t\t<file>%s/%s</file>\n",path_to_collection,files_names[h]);
		fprintf(fp_collection,"\t</static>\n");


		if (image_transition_time != 0.0){
			fprintf(fp_collection,"\t<transition>\n");
			fprintf(fp_collection,"\t\t<duration>%f</duration>\n",image_transition_time);
			fprintf(fp_collection,"\t\t<from>%s/%s</from>\n",path_to_collection,files_names[h]);
			fprintf(fp_collection,"\t\t<to>%s/%s</to>\n",path_to_collection,files_names[h + 1]);
			fprintf(fp_collection,"\t</transition>\n");
		}
	}

	fprintf(fp_collection,"\t<static>\n");
	fprintf(fp_collection,"\t\t<duration>%f</duration>\n",image_view_time);
	fprintf(fp_collection,"\t\t<file>%s/%s</file>\n",path_to_collection,files_names[h]);
	fprintf(fp_collection,"\t</static>\n");


	if (image_transition_time != 0.0){
		fprintf(fp_collection,"\t<transition>\n");
		fprintf(fp_collection,"\t\t<duration>%f</duration>\n",image_transition_time);
		fprintf(fp_collection,"\t\t<from>%s/%s</from>\n",path_to_collection,files_names[h]);
		fprintf(fp_collection,"\t\t<to>%s/%s</to>\n",path_to_collection,files_names[0]);
		fprintf(fp_collection,"\t</transition>\n");
	}


	fprintf(fp_collection,"</background>\n");



	for (h = 0; h < files_amount; h++){
		free(files_names[h]);
	}

	fclose(fp_collection);
	return EXIT_SUCCESS;
}
